using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Luka;

/// <summary>
/// 异常过滤
/// </summary>
[NotScanned]
public sealed class FriendlyExceptionFilter : IAsyncExceptionFilter
{
    /// <summary>
    /// 实现方法
    /// </summary>
    public async Task OnExceptionAsync(ExceptionContext context)
    {
        //判断异常是否为空
        if (context.Exception != null)
        {
            // 判断是否为友好异常
            if (context.Exception is FriendlyException friendlyException)
            {
                // 判断是否为验证异常
                if (friendlyException.ValidationException)
                {
                }
            }
            // 解析异常处理服务.打包后可实现自定义异常额外操作
            var exceptionHandler = context.HttpContext.RequestServices.GetService<IExceptionHandler>();
            if (exceptionHandler != null)
            {
                await exceptionHandler.OnExceptionAsync(context);
            }
            //不抛抛出异常信息
            var noError = context.GetAttribute<NoErrorAttribute>();
            if (noError != null)
            {
                context.Result = context.ReturnResult(noError?.Message);
            }
            //判断异常是否已处理
            else if (!context.ExceptionHandled)
            {
                var messageAttribute = context.GetAttribute<ErrorMessageAttribute>();
                object? result = messageAttribute != null ? messageAttribute : context.Exception;
                context.Result = context.ReturnResult(result, true);
                //记录日志(非自定义日志 and !非使用日志)
                if (context.Exception is not FriendlyException && !context.HasAttribute<NoLogAttribute>())
                {
                    //记录日志
                    context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>()
                        .CreateLogger(context.HttpContext.Request.Path)
                        .LogError(context.Exception, context.Exception.Message);
                }
                //标记异常已处理
                context.ExceptionHandled = true;
            }
        }
    }
}